import json

# Create your views here.
from . import tasks
from django.http import HttpResponse, StreamingHttpResponse
from .models import Task_result, Use_testcase
from . import serializers
import os
from django.views.generic import View
from django.core import serializers
from rest_framework.views import APIView
from utilspakage.writeconfig import CfgPar
from utilspakage.write_testcase import Writecase
import hashlib
from django.utils.encoding import escape_uri_path
from utilspakage.last_list_file import get_latest_file

MEDIARPATH = "/root/django32_celery/media/"
CONVERFILE = "/root/django32_celery/converfile/"
DOWNLOADFILE = '/root/django32_celery/download/'
CONFIGPATH = "/root/django32_celery/pytest.ini"


import logging

logger = logging.getLogger(__name__)


class DemoView(View):
    def get(self, request):
        pass

    def post(self, request):
        pass


# 什么是序列化
# 序列化器会将模型对象转换成字典，然后在经过response变化成json字符串
# 我们从数据库中读取的数据 是一个模型对象，不能直接变成json对象，所以需要序列化器将模型对象变化成json对象，
# 序列化器是面向模型对象的，所以说
# 一个模型对象对应一个序列化器


# 查看当前任务的执行状态  OK
class Getstatus(View):
    def get(self, request):
        return HttpResponse("OK")

    def post(self, request):
        parm = request.data
        print(f"post parm :{parm}")
        data = {
            # "msg": "DesignateTestcase",
            "errorcode": 0
        }
        return HttpResponse("OK2")


class DeviceManager(APIView):
    def get(self, req):
        print("DeviceManager get  入参 {}:".format({req.data}))
        data = {
            "msg": req.data
        }
        print("参考：https://zhuanlan.zhihu.com/p/661397637")

        return HttpResponse(json.dumps(data))

    def post(self, req):
        print("DeviceManager post 入参 {}:".format({req.data}))
        data = {
            "msg": req.data
        }
        print("参考：https://zhuanlan.zhihu.com/p/661397637")
        return HttpResponse(json.dumps(data))


# 模糊匹配查询  搜索测试用例   ok
class DesignateTestcase(APIView):
    async def post(self, request):
        parm = request.body
        params = parm.decode('utf-8')
        print(f"Post params :{params}")
        print(type(params))
        try:
            dt = Use_testcase.objects.filter(title__icontains=params)
            ret_ts = serializers.serialize('json', dt)

            data = {
                "msg": json.loads(ret_ts),
                "errorcode": 0
            }
            data = json.dumps(data)
            return HttpResponse(data)

        except Exception as e:
            print(e)


# 下载所选的测试用例
class DownLoadTestcase(APIView):
    def get(self, request):
        pass


# 下载文件模板
class DownloadApi(APIView):

    def post(self, request):
        print("Downloadfile  post  ")
        filepath = request.data
        filename = filepath['filename']
        print(f"filename:{filename}")

        file_path = DOWNLOADFILE + filepath['filename']
        print(f"file_path:{file_path}")

        with open(file_path, 'rb') as f:
            # 将文件以二进制形式读取
            file_data = f.read()
        response = HttpResponse(file_data, content_type='application/octet-stream')

        # 设置响应头，告诉浏览器返回的是附件，并指定文件名
        response['Content-Disposition'] = 'attachment; filename={0}'.format(escape_uri_path(filename))
        return response


class Downloadcoverfile(APIView):
    def post(self, request):
        print("Downloadcoverfile  post  ")
        filepath = request.data
        filename = filepath['filename']
        print(f"filename:{filename}")
        print(f'get_last_file:{get_latest_file(CONVERFILE)}')
        file_path = get_latest_file(CONVERFILE)

        print(f"file_path:{file_path}")

        with open(file_path, 'rb') as f:
            # 将文件以二进制形式读取
            file_data = f.read()
            print('读取文件内容.')
        response = HttpResponse(file_data, content_type='application/octet-stream')
        # 设置响应头，告诉浏览器返回的是附件，并指定文件名
        response['Content-Disposition'] = 'attachment; filename={0}'.format(escape_uri_path(filename))
        return response


class PyTest(APIView):
    def get(self, reqeust):
        res = tasks.api_test.apply_async()
        try:
            ts = Task_result(taskid=res.id, status=res.status, flag='1')
            ts.save()
            data = {
                "taskid": res.id,
                "status": res.status,
                'flag': 1
            }
            return HttpResponse(json.dumps(data))

        except Exception as e:
            print(e)


class ChoseTest(APIView):
    def get(self, request):
        print('开始执行 choose testchoose ')
        # 异步任务执行 task方式
        res = tasks.choosescript.apply_async()
        try:
            # 写入到任务结果表中
            ts = Task_result(taskid=res.id, status=res.status, flag="1")
            ts.save()
            data = {
                "taskid": res.id,
                "status": res.status,
                'flag': 1,
                'errorcode':0
            }
            return HttpResponse(json.dumps(data))

        except Exception as e:
            print(e)


# 获取执行脚本列表
class Getscriptlist(APIView):
    def get(self, request):
        file_list = os.listdir(MEDIARPATH)
        data = {
            "msg": file_list,
            "errorcode": 0
        }
        resp = json.dumps(data)
        return HttpResponse(resp)


class Writeconf(APIView):
    def post(self, request):
        par = (request.body).decode('utf-8')
        logger.info(f"选择执行的参数:{par}")
        dt = json.loads(par)
        # 写入配置文件
        cfg = CfgPar(CONFIGPATH)
        setctions = cfg.get_section()
        logger.info(setctions)
        cfg.update_values('testchoose', 'name', dt['name'])
        # 密码加密
        md = hashlib.md5((dt['passwd']).encode())
        cfg.update_values('testchoose', 'passwd', md.hexdigest())
        cfg.update_values('testchoose', 'environment', dt['environment'])
        cfg.update_values('testchoose', 'scrlist', dt['scrlist'])
        cfg.update_values('testchoose', 'flag', "1")
        # logger.info(f"选择执行的参数:{cfg.get_value(setctions['testchoose'],'scrlist')}")

        data = {
            "msg": f'更新: over ！',
            "errorcode": 0
        }
        return HttpResponse(json.dumps(data))


# 上传文件 指定excel 类型
class UpLoadFile(APIView):
    def post(self, request):
        file = request.FILES.get('file')
        print(file.name)
        # 判断上传上来的文件是否是excel
        allowed_extensions = ['xls', 'xlsx']
        # 获取文件扩展名
        file_extension = file.name.split('.')[-1]
        if file_extension.lower() in allowed_extensions:
            # 存入到指定的media文件中test_data,
            destination = open(os.path.join(MEDIARPATH, file.name), 'wb+')  # 打开特定的文件进行二进制的写操作
            for chunk in file.chunks():  # 分块写入文件
                destination.write(chunk)
            destination.close()
            data = {
                "msg": str('文件上传成功'),
                "errorcode": 0
            }
            data = json.dumps(data)
            return HttpResponse(data)
        else:
            data = {
                "msg": '上传文件类型不符，请上传正确的文件',
                "errorcode": -100
            }
            data = json.dumps(data)
            return HttpResponse(data)


# 转换文件上传处理
class ConversionFile(APIView):
    def post(self, request):
        file = request.FILES.get('file')
        print(file.name)
        # 判断上传上来的文件是否是excel
        allowed_extensions = ['xls', 'xlsx']
        # 获取文件扩展名
        file_extension = file.name.split('.')[-1]
        if file_extension.lower() in allowed_extensions:
            # 存入CONVERFILE
            destination = open(os.path.join(CONVERFILE, file.name), 'wb+')  # 打开特定的文件进行二进制的写操作
            for chunk in file.chunks():  # 分块写入文件
                destination.write(chunk)
            destination.close()
        ts = Writecase(CONVERFILE + file.name)
        ts.write_testcase_to_excel(ts.getsheet() + "-用例转化", ts.wc())
        data = {
            "msg": '文件上传成功,已经转换成功请主动下载',
            "errorcode": 0
        }
        data = json.dumps(data)
        return HttpResponse(data)


# 全部结果查询 ，limit 数量   OK
class AllTestcase(APIView):
    def get(self, request):
        try:
            ts = Use_testcase.objects.all().order_by('-id')[:50]
            # 实例化序列   django里面有个serializers方法可以，直接把查询的结果转成json数据
            ret_ts = serializers.serialize('json', ts)
            print(ret_ts)
            data = {
                "msg": json.loads(ret_ts),
                "errorcode": 0
            }
            return HttpResponse(json.dumps(data))
        except Exception as e:
            print(e)

    def post(self, request):
        parm = request.data
        print(f"post parm :{parm}")
        pass


# 任务查询  OK
class QueryTask(View):
    def get(self, request):
        try:
            ts = Task_result.objects.all().order_by('-id')[:10]
            # 实例化序列   django里面有个serializers方法可以，直接把查询的结果转成json数据
            ret_ts = serializers.serialize('json', ts)
            # print(ret_ts)
            data = {
                "msg": json.loads(ret_ts),
                "errorcode": 0
            }
            return HttpResponse(json.dumps(data))

        except Exception as e:
            print(e)
            data = {
                "msg": [],
                "errorcode": 0
            }
            return HttpResponse(json.dumps(data))


# 邮件测试
class Email_test(View):
    def get(self, request):
        res = tasks.devicemanager.apply_async(args=[10, ])
        # 用get拿到返回的结果
        print(f'任务结果：devicemanager ID ：{res.id}   result :{res.status}')
        # 新增结果,写入到sqlite中
        try:
            ts = Task_result(taskid=res.id, status=res.status, flag='1')
            ts.save()
            data = {
                "taskid": res.id,
                "status": res.status,
                'flag': 1
            }
            return HttpResponse(json.dumps(data))

        except Exception as e:
            print(e)


def demo(request):
    print('当前执行的任务。。。。')
    res1 = tasks.send_sms.apply_async()
    res2 = tasks.send_sms2.apply_async()

    # 用get拿到返回的结果
    print(f'任务结果：res1 ID ：{res1.id}   result :{res1.status}')
    print(f'任务结果：res2 ID ：{res2.id}   result :{res2.status}')

    res_data = {
        'code': 0,
        "message": "success!",
        "data":
            {
                "res1": res1,
                "res2": res2
            }
    }

    return HttpResponse("task is running ...")


def devicemanager(request):
    print("device manager task")
    res1 = tasks.devicemanager.apply_async()
    print(f'任务结果：res1 ID ：{res1.id}   result :{res1.status}')
    # 新增结果,写入到sqlite中
    # try:
    #     ts = Celery_Result_model(taskid=res1.id, status=res1.status)
    #     ts.save()
    # except Exception as e:
    #     print(e)

    return HttpResponse("I will start device register devicemanager !")

# class TaskView(ModelViewSet):
#     serializer_class = serializers.CeleryModelSerializer
#     queryset = models.Celery_Result_model.objects.all()

# serializer_class：指明该视图在进行序列化或反序列化时使用的序列化器
# queryset：指明该视图集在查询数据时使用的查询集
